package com.kc.web.controller.business;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.kc.business.domain.BizMenu;
import com.kc.business.domain.vo.BizMenuVo;
import com.kc.business.enums.MenuTypeEnum;
import com.kc.business.service.IBizMenuService;
import com.kc.common.annotation.Log;
import com.kc.common.annotation.RepeatSubmit;
import com.kc.common.constant.Constants;
import com.kc.common.core.controller.BaseController;
import com.kc.common.core.domain.AjaxResult;
import com.kc.common.core.domain.model.LoginUser;
import com.kc.common.core.page.TableDataInfo;
import com.kc.common.enums.BusinessType;
import com.kc.common.utils.ServletUtils;
import com.kc.common.utils.StringUtils;
import com.kc.framework.web.service.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * FileName: BizMenuController
 * Author:   TP
 * Date:     2020-10-30 08:32
 * Description: 菜单控制器
 */
@Slf4j
@RestController
@RequestMapping("/business/menu")
public class BizMenuController extends BaseController {

    @Autowired
    private IBizMenuService bizMenuService;

    @Autowired
    private TokenService tokenService;

    /**
     * 获取菜单列表
     */
    @GetMapping("/list")
    public TableDataInfo getList(BizMenuVo vo) {
        startPage();
        List<BizMenu> list = bizMenuService.getList(vo);
        return getDataTable(list);
    }

    /**
     * 获取菜单详情
     */
    @GetMapping("/info/{id}")
    public AjaxResult getInfo(@PathVariable Integer id) {
        if (id != null && id > 0) {
            return AjaxResult.success(bizMenuService.getById(id));
        }
        return AjaxResult.error("请选择一条记录");
    }

    /**
     * 获取所有菜单组（未删除的）
     */
    @GetMapping("/activeGroupMenus")
    public AjaxResult getGroup() {
        BizMenuVo vo = new BizMenuVo();
        List<BizMenu> allMenus = bizMenuService.getList(vo);
        List<Map<String, Object>> groupMenusInfo = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(allMenus)) {
            List<BizMenu> groupMenus = allMenus.stream().filter(e ->
                    MenuTypeEnum.GROUP.getType().equals(e.getMenuType()))
                    .sorted(Comparator.comparing(BizMenu::getMenuSort))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(groupMenus)) {
                for (BizMenu groupMenu : groupMenus) {
                    Map<String, Object> map = Maps.newHashMap();
                    map.put("groupMenuId", groupMenu.getId());
                    map.put("groupMenuName", groupMenu.getMenuName());
                    groupMenusInfo.add(map);
                }
            }
        }
        return AjaxResult.success(groupMenusInfo);
    }

    /**
     * 获取树形动态菜单列表
     */
    @GetMapping("/activePersonalTreeList")
    public AjaxResult getActivePersonalTreeList(Integer roleId) {
        Map<String, Object> result = bizMenuService.getActivePersonalTreeMenus(roleId);
        return AjaxResult.success(result);
    }

    @RepeatSubmit
    @Log(title = "新增动态菜单", businessType = BusinessType.INSERT)
    @PreAuthorize("@ss.hasPermi('business:dynamicMenu:add')")
    @PostMapping("/add")
    public AjaxResult add(@Validated @RequestBody BizMenu bizMenu) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        if (loginUser != null) {
            if (MenuTypeEnum.GROUP.getType().equals(bizMenu.getMenuType())) {
                // 如果是组
                bizMenu.setIsCommon(Integer.parseInt(Constants.YES));
            } else {
                // 额外校验菜单图标不能为空
                if (StringUtils.isEmpty(bizMenu.getMenuIcon())) {
                    return AjaxResult.error("菜单图标不能为空");
                }
                if (Constants.YES.equals(String.valueOf(bizMenu.getIsH5()))) {
                    // 如果是h5校验链接必填
                    if (StringUtils.isEmpty(bizMenu.getMenuLink())) {
                        return AjaxResult.error("菜单为H5页面时，菜单链接必填");
                    }
                }
            }
            AjaxResult checkResult = checkExist(bizMenu);
            if (checkResult != null) {
                return checkResult;
            }
            bizMenu.setCreateBy(loginUser.getUsername());
            bizMenu.setCreateTime(new Date());
            if (bizMenuService.add(bizMenu) > 0) {
                return AjaxResult.success();
            }
            return AjaxResult.error("操作失败，数据库插入失败");
        }
        return AjaxResult.error("操作失败，未获取到当前登陆人信息");
    }

    @RepeatSubmit
    @Log(title = "修改动态菜单", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('business:dynamicMenu:update')")
    @PutMapping("/update")
    public AjaxResult update(@Validated @RequestBody BizMenu bizMenu) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        if (loginUser != null) {
            BizMenu existBizMenu1 = bizMenuService.getByAppFlagId(bizMenu.getAppFlagId());
            if (existBizMenu1 != null && !existBizMenu1.getId().equals(bizMenu.getId())) {
                return AjaxResult.error("操作失败，已存在此App标识位对应的菜单");
            }
            BizMenu existBizMenu2 = bizMenuService.getByMenuName(bizMenu.getMenuName());
            if (existBizMenu2 != null && !existBizMenu2.getId().equals(bizMenu.getId())) {
                return AjaxResult.error("操作失败，已存在此名称的菜单");
            }
            if (MenuTypeEnum.MENU.getType().equals(bizMenu.getMenuType())) {
                // 额外校验菜单图标不能为空
                if (StringUtils.isEmpty(bizMenu.getMenuIcon())) {
                    return AjaxResult.error("菜单图标不能为空");
                }
                if (Constants.YES.equals(String.valueOf(bizMenu.getIsH5()))) {
                    // 如果是h5校验链接必填
                    if (StringUtils.isEmpty(bizMenu.getMenuLink())) {
                        return AjaxResult.error("菜单为H5页面时，菜单链接必须填写");
                    }
                }
            }
            bizMenu.setUpdateBy(loginUser.getUsername());
            bizMenu.setUpdateTime(new Date());
            if (bizMenuService.updateById(bizMenu) > 0) {
                return AjaxResult.success();
            }
            return AjaxResult.error("操作失败，数据库更新失败");
        }
        return AjaxResult.error("操作失败，未获取到当前登陆人信息");
    }

    @RepeatSubmit
    @Log(title = "删除动态菜单", businessType = BusinessType.DELETE)
    @PreAuthorize("@ss.hasPermi('business:dynamicMenu:delete')")
    @DeleteMapping("/delete/{id}")
    public AjaxResult delete(@PathVariable Integer id) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        if (loginUser != null) {
            return bizMenuService.deleteById(id, loginUser.getUsername());
        }
        return AjaxResult.error("操作失败，未获取到当前登陆人信息");
    }


    private AjaxResult checkExist(BizMenu bizMenu) {
        BizMenu existBizMenu = bizMenuService.getByMenuNameOrAppFlagId(bizMenu.getMenuName(), bizMenu.getAppFlagId());
        if (existBizMenu != null) {
            if (bizMenu.getMenuName().equals(existBizMenu.getMenuName())) {
                return AjaxResult.error(String.format("操作失败，已存在名称为[%s]的菜单", bizMenu.getMenuName()));
            }
            return AjaxResult.error(String.format("操作失败，已存在App标识位为[%s]的菜单", bizMenu.getAppFlagId()));
        }
        if (MenuTypeEnum.MENU.getType().equals(bizMenu.getMenuType())) {
            if (bizMenu.getParentMenuId() == null) {
                return AjaxResult.error("操作失败，非组菜单必须指定所属组");
            }
            BizMenu parentMenu = bizMenuService.getById(bizMenu.getParentMenuId());
            if (parentMenu == null || parentMenu.getIsDeleted().equals(Constants.DELETE)) {
                return AjaxResult.error("操作失败，未找到所属菜单组信息");
            }
        }
        return null;
    }

}
